/*
 * MIT License
 *
 * Copyright (c) 2023 北京凯特伟业科技有限公司
 *
 * Permission is hereby granted, free of charge, to any person obtaining a copy
 * of this software and associated documentation files (the "Software"), to deal
 * in the Software without restriction, including without limitation the rights
 * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
 * copies of the Software, and to permit persons to whom the Software is
 * furnished to do so, subject to the following conditions:
 *
 * The above copyright notice and this permission notice shall be included in all
 * copies or substantial portions of the Software.
 *
 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
 * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
 * SOFTWARE.
 */
package com.je.rbac.service.threemember.impl;

import com.je.common.base.DynaBean;
import com.je.common.base.context.GlobalExtendedContext;
import com.je.common.base.exception.PlatformException;
import com.je.common.base.exception.PlatformExceptionEnum;
import com.je.common.base.service.CommonService;
import com.je.common.base.service.MetaService;
import com.je.common.base.util.DateUtils;
import com.je.ibatis.extension.conditions.ConditionsWrapper;
import com.je.rbac.cache.ThreeMemberSettingCache;
import com.je.rbac.service.threemember.ThreeMemberSettingService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import static com.je.rbac.service.role.impl.RbacRoleServiceImpl.ROLE_TYPE_CODE;
import static com.je.rbac.service.role.impl.RbacRoleServiceImpl.ROLE_TYPE_NAME;

@Service
public class ThreeMemberSettingServiceImpl implements ThreeMemberSettingService {

    /**
     * 安全审计员角色
     */
    public static final String AUTI_MANAGER_ROLE = "auditRole";
    /**
     * 安全管理员角色
     */
    public static final String SECURITY_MANAGER_ROLE = "securityRole";
    /**
     * 系统管理员角色
     */
    public static final String SYSTEM_MANAGER_ROLE = "systemRole";

    @Autowired
    private MetaService metaService;
    @Autowired
    private ThreeMemberSettingCache threeMemberSettingCache;
    @Autowired
    private CommonService commonService;

    @Override
    @Transactional
    public void installThreeMemberManage(DynaBean settingBean) {
        if (!"1".equals(settingBean.getStr("THREEMSETTING_OPEN_CODE"))) {
            throw new PlatformException("请先开启三员管理再执行初始化操作！", PlatformExceptionEnum.UNKOWN_ERROR);
        }

        //创建初始化角色
        createRole(AUTI_MANAGER_ROLE, "安全审计员");
        createRole(SECURITY_MANAGER_ROLE, "安全管理员");
        createRole(SYSTEM_MANAGER_ROLE, "系统管理员");

        createRoleResource(AUTI_MANAGER_ROLE, "安全审计员");
        createRoleResource(SECURITY_MANAGER_ROLE, "安全管理员");
        createRoleResource(SYSTEM_MANAGER_ROLE, "系统管理员");

        //设置系统状态上下文和缓存
        Map<String, String> mapValues = new HashMap<>();
        mapValues.put("switch", "1");
        mapValues.put("auditManagerLogSwitch", settingBean.getStr("THREEMSETTING_AUDITLOG_CODE"));
        mapValues.put("securityManagerLogSwitch", settingBean.getStr("THREEMSETTING_MANLOG_CODE"));
        mapValues.put("systemManagerLogSwitch", settingBean.getStr("THREEMSETTING_SYSLOG_CODE"));
        mapValues.put("auditRole", AUTI_MANAGER_ROLE);
        mapValues.put("securityRole", SECURITY_MANAGER_ROLE);
        mapValues.put("systemRole", SYSTEM_MANAGER_ROLE);
        threeMemberSettingCache.putMapCache(mapValues);
        GlobalExtendedContext.putAll(mapValues);

        //更改初始化状态
        settingBean.set("THREEMSETTING_INIT_CODE","1");
        settingBean.set("THREEMSETTING_INIT_NAME","是");
        metaService.update(settingBean);
    }

    @Override
    public void unInstallThreeMemberManage(DynaBean settingBean) {
        metaService.delete("JE_RBAC_ROLE", ConditionsWrapper.builder().eq("JE_RBAC_ROLE_ID", AUTI_MANAGER_ROLE));
        metaService.delete("JE_RBAC_ROLE", ConditionsWrapper.builder().eq("JE_RBAC_ROLE_ID", SECURITY_MANAGER_ROLE));
        metaService.delete("JE_RBAC_ROLE", ConditionsWrapper.builder().eq("JE_RBAC_ROLE_ID", SYSTEM_MANAGER_ROLE));
        String[] keys = new String[]{
                "switch",
                "auditManagerLogSwitch",
                "systemManagerLogSwitch",
                "securityManagerLogSwitch",
                "auditRole",
                "securityRole",
                "systemRole"
        };
        threeMemberSettingCache.clear();
        GlobalExtendedContext.removeContext(keys);

        //更改初始化状态
        settingBean.set("THREEMSETTING_INIT_CODE","0");
        settingBean.set("THREEMSETTING_INIT_NAME","否");
        metaService.update(settingBean);
    }

    /**
     * 创建安全审计员角色
     */
    private void createRole(String roleId, String roleName) {
        DynaBean roleBean = metaService.selectOne("JE_RBAC_ROLE", ConditionsWrapper.builder().eq("JE_RBAC_ROLE_ID", roleId));
        if (roleBean != null) {
            return;
        }

        List<Map<String, Object>> countList = metaService.selectSql("SELECT MAX(SY_ORDERINDEX) AS MAX_COUNT FROM JE_RBAC_ROLE");
        int count = (int) countList.get(0).get("MAX_COUNT");
        List<Map<String, Object>> currentChildList = metaService.selectSql("SELECT COUNT(*) AS TOTAL_COUNT FROM JE_RBAC_ROLE WHERE SY_PARENT = {0}", "ROOT");
        long currentChildCount = (long) currentChildList.get(0).get("TOTAL_COUNT");
        roleBean = new DynaBean("JE_RBAC_ROLE", false);
        roleBean.set("JE_RBAC_ROLE_ID", roleId);
        roleBean.set("ROLE_NAME", roleName);
        roleBean.set("ROLE_CODE", "role-" + String.format("%06d", count + 1));
        roleBean.set("ROLE_TYPE_CODE", ROLE_TYPE_CODE);
        roleBean.set("ROLE_TYPE_NAME", ROLE_TYPE_NAME);

        //树形节点值
        roleBean.set("SY_PARENT", "ROOT");
        roleBean.set("SY_PARENTPATH", "/ROOT");
        roleBean.set("SY_LAYER", 1);
        roleBean.set("SY_STATUS", "1");
        roleBean.set("SY_NODETYPE", "LEAF");
        roleBean.set("SY_PATH", "/ROOT" + "/" + roleId);
        roleBean.set("SY_TREEORDERINDEX", "000001" + String.format("%06d", currentChildCount + 1));
        //创建时间
        roleBean.set("SY_CREATETIME", DateUtils.formatDateTime(new Date()));
        roleBean.set("ROLE_DEVELOP", "0");
        roleBean.set("SY_ORDERINDEX", count + 1);
        commonService.buildModelCreateInfo(roleBean);
        metaService.insert(roleBean);
    }

    private void createRoleResource(String roleId, String roleName) {
        DynaBean roleResourceScope = metaService.selectOne("JE_RBAC_RESOURCESCOPE", ConditionsWrapper.builder().eq("RESOURCESCOPE_ROLE_ID", roleId));
        if (roleResourceScope != null) {
            return;
        }
        roleResourceScope = new DynaBean("JE_RBAC_RESOURCESCOPE", false);
        roleResourceScope.set("RESOURCESCOPE_ROLE_ID", roleId);
        roleResourceScope.set("RESOURCESCOPE_ROLE_NAME", roleName);
        roleResourceScope.set("RESOURCESCOPE_REMARK", "初始化生成！");
        roleResourceScope.set("SY_STATUS","1");
        commonService.buildModelCreateInfo(roleResourceScope);
        metaService.insert(roleResourceScope);
    }

}
